package com.yayako.utils.EasyExcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.yayako.modules.user.mapper.UserMapper;
import com.yayako.result.Result;
import com.yayako.result.ResultFactory;
import com.yayako.utils.common.ApplicationContextUtil;
import org.springframework.dao.DataAccessException;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/** @author cyy */
public class ImportListener extends AnalysisEventListener<Object> {
  private static final int BATCH_COUNT = 5;
  private static UserMapper userMapper = ApplicationContextUtil.getBean(UserMapper.class);
  private List<Object> list = new ArrayList<>();
  private List<String> msgs = new ArrayList<>();
  private Result result = null;

  public List<Object> getList() {
    return list;
  }

  public void setList(List<Object> list) {
    this.list = list;
  }

  public Result getResult() {
    result = ResultFactory.bulidSuccessResult(msgs);
    return result;
  }

  public void setResult(Result result) {
    this.result = result;
  }

  @Override
  public void invoke(Object o, AnalysisContext analysisContext) {
    list.add(o);
    if (list.size() >= BATCH_COUNT) {
      userMapper.bulkInsert(list);
      list.clear();
    }
  }

  /**
   * 将Object转换为Map
   *
   * @param o 对象
   * @return map
   * @throws IllegalAccessException 安全检查异常
   */
  private Map<String, Object> objToMap(Object o) throws IllegalAccessException {
    Map<String, Object> map = new LinkedHashMap<>();
    Field[] fields = o.getClass().getDeclaredFields(); // 获取所有字段
    for (Field f : fields) {
      f.setAccessible(true); // 关闭访问安全检查
      map.put(f.getName(), f.get(o)); // 返回指定对象上由f表示的字段的值
    }
    return map;
  }

  @Override
  public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    userMapper.bulkInsert(list);
    System.out.println(result);
    list.clear();
  }

  /**
   * 异常回调
   *
   * @param exception 异常
   * @param context 当前行内容
   * @throws Exception 抛出异常
   */
  @Override
  public void onException(Exception exception, AnalysisContext context) throws Exception {
    int row = context.readRowHolder().getRowIndex();
    if (exception instanceof ExcelDataConvertException) { // 数据转换异常
      int columnNum = ((ExcelDataConvertException) exception).getColumnIndex() + 1;
      int rowNum = ((ExcelDataConvertException) exception).getRowIndex() + 1;
      msgs.add("第" + rowNum + "行，第" + columnNum + "列数据格式有误！");
    } else if (exception instanceof DataAccessException) { // 数据存储异常
      msgs.add("第" + row + "行数据有误，插入数据库失败。\n" + exception.getCause().getMessage());
    } else if (exception instanceof RuntimeException) {
      msgs.add("第" + row + "行数据有误。\n" + exception.getCause().getMessage());
    } else {
      super.onException(exception, context);
    }
  }
}
